;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun multiplicative-order2 (k n &rest rs)
  "Gives the multiplicative order of K modulo N; or, the
   smallest integer M such that (= (mod (expt K M) N) R)
   for some R.  If no Rs are provided, 1 is used."
  (let ((rs (or rs '(1))))
    (loop for m from 1
          when (member (mod (expt k m) n) rs :test #'=)
            do (return m))))

;;; TODO ;;;
;;; a. how to calculate period number for, for instance 6/12
;;; b. how multiplicative-order works for this problem.
;;;;;;;;;;;;

;;; n is relatively prime to b.
(defun multiplicative-order (&key (b 10) n)
  (loop for e from 1 to (1- n)
        when (zerop (mod (1- (expt b e)) n))
        do (return (cons n e))))

(defun max-complex (alist blist)
  (if (>= (cdr alist) (cdr blist))
      alist
      blist))
;  (when ((null (cdr blist)) alist)
 ;       ((>= (cdr alist) (cdar blist))
  ;       (max-complex alist (cdr blist)))
   ;     (t (max-complex (car blist) (cdr blist)))))

(defun p26 ()
  (reduce 'max-complex
    (remove nil
    (loop for i from 1 to 1000
          when (= 1 (gcd i 10))
          collect (multiplicative-order :n i)))))

(format t "~a~%" (multiplicative-order  :n 983))
(format t "~a~%" (time (p26)))
;(format t "~a~%" (max-complex (cons 12 23) (cons 13 43)))

